package kayao.client.network.message;

import java.util.Vector;

import kayao.client.data.SharedMemory;
import kayao.client.data.Slave;
import kayao.common.Client;
import kayao.common.KayaoValues;
import kayao.common.NetworkUtils;

public class SubscriptionRequestMessage extends Message{
	private static final int RETRIES = 1;
	//private static final int TIMEOUT_LENGTH_MILLIS = 2000;
	private static final int PRIORITY = PRIORITY_MEDIUM;
	private static int mLastMessageId=0;
	private int mKingdom=0;

	public SubscriptionRequestMessage(String targetAddress, int timeout, int kingdom) {
		super(targetAddress, RETRIES, timeout, PRIORITY);
		mKingdom=kingdom;
		createPacketData();
		if(mMessageId>mLastMessageId)
			mLastMessageId=mMessageId;
	}

	@Override
	public String type() {
		// TODO Auto-generated method stub
		return "Subscription Request";
	}
	public static int getLastMessageId()
	{
		return mLastMessageId;
	}
	@Override
	public void createPacketData() {
		String mName = SharedMemory.getInstance().getName();

		// 4(magic number), 1(message id), 4(message counter), 4(local client id), 1(local team id), 1(current region id),
		// 1(name length), 1(letter in name) * name length = 12+name length
		mSendData = new byte[16 + mName.length()];
		int index = 0;

		// Insert magic number (int32)
		NetworkUtils.insertIntToByteArray(mSendData, index, KayaoValues.MAGIC_NUMBER);
		index += 4;
		// Insert message id (b)
		mSendData[index] = KayaoValues.SUSCRIPTION_REQUEST;
		index++;
		//Insert message counter
		NetworkUtils.insertIntToByteArray(mSendData, index, mMessageId);
		index += 4;
		// Insert local client id (int32)
		NetworkUtils.insertIntToByteArray(mSendData, index, SharedMemory.getInstance().getLocalId());
		index += 4;
		// Insert local team ID (b)
		mSendData[index] = (byte)SharedMemory.getInstance().getLocalTeamId();
		index++;
		// Insert current region ID (b)
		mSendData[index] = (byte)mKingdom;
		index++;
		// Insert name length
		mSendData[index] = (byte)mName.length();
		index++;

		// Letters in name
		for (int i = 0; i < mName.length(); i++)
			mSendData[index + i] = (byte)mName.charAt(i);
	}

	public static void processPacketData(byte[] data, String ip) {

		int kingdom;
		if((kingdom = Slave.getKingdomFromIP(ip))!= -1){ // If king has not been removed

			// Create new 
			Vector<Integer> newSubscriberList = new Vector<Integer>();		

			int index = 9;	// Index starts at 5 because previous data already used. (Magic number + id)

			// Check how many team mates are in AoI
			short numberOfTeamMates=NetworkUtils.insertByteArrayToShort(data, index);
			index += 2;
			//System.out.println("Number of teammates: " + numberOfTeamMates);
			for(int i=0; i<numberOfTeamMates; i++){
				int teamMateId = NetworkUtils.insertByteArrayToInt(data, index);
				// Put ID in list of subscribers, team mates are already stored
				newSubscriberList.add(teamMateId);
				//System.out.println("Teammate ID: " + teamMateId);
				index += 4;
			}

			// Check how many enemies there are in AoI
			short numberOfEnemies = NetworkUtils.insertByteArrayToShort(data, index);
			index += 2;
			//System.out.println("Number of enemies: " + numberOfEnemies);
			for(int i=0; i<numberOfEnemies; i++){
				int enemyId = NetworkUtils.insertByteArrayToInt(data, index);
				index += 4;

				// Check if we already have client stored,
				// if so just put it in subscriber list
				//System.out.println("Enemy ID: " + enemyId);

				// Get client ip (4x(b))
				final int first = NetworkUtils.unsignedByteToInt(data[index]);
				final int second = NetworkUtils.unsignedByteToInt(data[index + 1]);
				final int third = NetworkUtils.unsignedByteToInt(data[index + 2]);
				final int fourth = NetworkUtils.unsignedByteToInt(data[index + 3]);
				index += 4;	
				String enemyIp = first+"."+second+"."+third+"."+fourth;

				int nameLength = NetworkUtils.unsignedByteToInt(data[index]);
				index++;
				// Get client name
				String clientName = "";
				for (int j = 0; j < nameLength; j++) {
					clientName += (char)data[index];
					index ++;
				}
				if(!SharedMemory.getInstance().hasClient(enemyId))
					SharedMemory.getInstance().addClient(new Client(clientName, enemyId, enemyIp, -1));
				newSubscriberList.add(enemyId);
			}
			SharedMemory.getInstance().updateSubscriberList(newSubscriberList, kingdom);
		}
	}
}
